﻿using GN.Pay.TradeChannel.DefaultImpl;
using GN.Pay.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GN.Pay.TradeChannel.AliPay.Response
{
    [Serializable]
    public class QueryResponse : AResponse
    {
        /// <summary>
        /// 查询响应
        /// </summary>
        private readonly ITradeChannel channel;
        private readonly AliPayConfigure config;
        private TradeOrderQueryResult orderQueryResult;

        internal QueryResponse(string responseString,
            ITradeChannel channel,
            AliPayConfigure config)
        {
            if (responseString != null)
            {
                this.ResponseString = responseString.Trim();
            }
            else
            {
                this.ResponseString = responseString;
            }
            this.channel = channel;
            this.config = config;
            this.Init();
        }

        private static string Format_ErrorMessage = "响应结果格式不正确，没有该订单号或者流水号的订单信息。";

        private void Init()
        {
            if (string.IsNullOrWhiteSpace(this.ResponseString))
            {
                this.channel.ThrowInterfaceException(Format_ErrorMessage);
            }
            IDictionary<string, object> xmlDic;
            try
            {
                xmlDic = XmlUtils.LoadXmlString(this.ResponseString, "alipay");
            }
            catch
            {
                throw this.channel.ThrowInterfaceException(Format_ErrorMessage);
            }
            object is_success;
            if (!xmlDic.TryGetValue("is_success", out is_success) || is_success == null)
            {
                throw this.channel.ThrowInterfaceException(Format_ErrorMessage);
            }
            if (is_success.ToString().Equals("T", StringComparison.InvariantCultureIgnoreCase))
            {
                this.IsSuccess = true;
                object trade;
                if (!xmlDic.TryGetValue("response", out trade) || trade == null)
                {
                    throw this.channel.ThrowInterfaceException(Format_ErrorMessage);
                }
                Dictionary<string, object> result = new Dictionary<string, object>();
                result = trade as Dictionary<string, object>;
                object Rtrade, buyer_email, body, buyer_id, gmt_create, out_trade_no, total_fee, subject, trade_no, trade_status;
                Dictionary<string, object> tradeResult;
                result.TryGetValue("trade", out Rtrade);
                if (Rtrade == null)
                {
                    orderQueryResult = null;
                    return;
                }
                tradeResult = Rtrade as Dictionary<string, object>;

                tradeResult.TryGetValue("buyer_email", out buyer_email);
                tradeResult.TryGetValue("body", out body);
                tradeResult.TryGetValue("buyer_id", out buyer_id);
                tradeResult.TryGetValue("gmt_create", out gmt_create);
                tradeResult.TryGetValue("out_trade_no", out out_trade_no);
                tradeResult.TryGetValue("total_fee", out total_fee);
                tradeResult.TryGetValue("subject", out subject);
                tradeResult.TryGetValue("trade_no", out trade_no);
                tradeResult.TryGetValue("trade_status", out trade_status);
                if (trade_status.Equals("TRADE_SUCCESS") || trade_status.Equals("BUYER_PRE_AUTH") || trade_status.Equals("TRADE_FINISHED"))
                {
                    orderQueryResult = new TradeOrderQueryResult(this.channel)
                    {
                        TradeNo = trade_no.ToString(),
                        Body = body.ToString(),
                        OrderNo = out_trade_no.ToString(),
                        OtherPartyAccount = buyer_email.ToString(),
                        Subject = subject.ToString(),
                        OrderMoney = Convert.ToDecimal(total_fee.ToString()),
                        OtherPartyAccountId = buyer_id.ToString(),
                        PayTime = Convert.ToDateTime(gmt_create),
                        PayFee = 0m,
                    };
                }
                else
                {
                    orderQueryResult = null;
                    return;
                }
            }
            else
            {
                orderQueryResult = null;
                return;
            }
        }

        /// <summary>
        /// 获取响应字符
        /// </summary>
        public string ResponseString { get; private set; }

        /// <summary>
        /// 获取是否成功
        /// </summary>
        public bool IsSuccess { get; private set; }

        /// <summary>
        /// 获取错误代码
        /// </summary>
        public string ErrorCode { get; private set; }

        /// <summary>
        /// 转为结果
        /// </summary>      
        /// <returns></returns>
        public ITradeOrderQueryResult ToResult()
        {
            var msg = "";
            if (!this.IsSuccess)
            {
                msg = this.ErrorCode;
            }
            return orderQueryResult;
        }
    }
}

